package com.pinc.cpbl;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class myHTMLparser {

	public BufferedInputStream stream;
	
	private static final int READ_LEN =1000;
	private static final int FRAME_SIZE = 600;
	private byte[] buf;
	
	protected String charset;

	public myHTMLparser(InputStream istream, String charset) {
		super();
		stream = new BufferedInputStream(istream, 1024);
		buf = new byte[READ_LEN];
		this.charset = charset;
	}

	public String getTagName()
	{
		Pattern p = Pattern.compile("[^<>\\s]+");
		Matcher m2;
		int len;
		String tagName = new String();

		try {
			stream.mark(READ_LEN);
			len = stream.read(buf, 0, READ_LEN);		
			String str = new String(buf, 0, len);
			m2 = p.matcher(str);
			if(m2.find())
				tagName = m2.group();
			else
				tagName = "";
			stream.reset();
			return tagName;
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}
	}
	public boolean nextTag()
	{
		int index = -1;
		int bytes_read;
		String str;

		try {
			skipBytes(1);
			do
			{
				stream.mark(READ_LEN);
				bytes_read = readBytes(READ_LEN);
				str = new String(buf, 0, bytes_read, charset);
				index = str.indexOf("<");
				if(index >= 0)
					break;
				stream.reset();
				skipBytes(FRAME_SIZE);
			}while(bytes_read == READ_LEN);

			if ( index >= 0 )
			{
				stream.reset();
				skipBytes(str.substring(0, index).getBytes(charset).length);
				return true;
			}
			return false;
		} catch (IOException e1) {
			e1.printStackTrace();
			return false;
		}
	}

	public boolean gotoTag(String TagName)
	{	
		int index = -1;
		int bytes_read;
		String srhStr = String.format("<%s", TagName); 
		String str;

		try {
			do
			{
				stream.mark(READ_LEN);
				bytes_read = readBytes(READ_LEN);
				str = new String(buf, 0, bytes_read, charset);
				index = str.indexOf(srhStr);
				if ( index != -1)
					break;
				stream.reset();
				skipBytes(FRAME_SIZE);
			}while( bytes_read == READ_LEN );
			if ( index != -1)
			{
				stream.reset();
				skipBytes(str.substring(0, index).getBytes(charset).length);
				return true;
			}
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	public boolean gotoTagByProp(String TagName, String Prop, String Val)
	{	
		boolean find=false;
		int bytes_read;
		String srhStr = String.format("<(\\s)*%s[^>]+%s=\"%s\".*>", TagName, Prop, Val);
		Pattern p = Pattern.compile(srhStr, Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
		Matcher m;
		String str;
		try {
			do
			{
				stream.mark(READ_LEN);
				bytes_read = readBytes(READ_LEN);
				str = new String(buf, 0, bytes_read, charset);
				m = p.matcher(str);
				if ( m.find())
				{
					find = true;
					break;
				}
				stream.reset();
				skipBytes(FRAME_SIZE);
			}while( bytes_read == READ_LEN);
			if (find)
			{
				stream.reset();
				skipBytes(str.substring(0, m.start()).getBytes(charset).length);
				return true;
			}
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	protected boolean checkTable()
	{
		String retStr = getTagName();
		if ( retStr.compareTo("table") != 0)
			return false;
		return true;
	}

	public int readBytes(int read_len) throws IOException
	{
		int highwater = 0;
		int len;
		do
		{
			len = stream.read(buf, highwater, read_len-highwater);
			highwater+=len;
		}while(len > 0 && highwater < read_len);
		return highwater;
	}

	public int skipBytes(int skip_len) throws IOException
	{
		int highwater = 0;
		int len;
		do{
			len = stream.read(buf, highwater, skip_len-highwater);
			highwater+=len;
		}while(len > 0 && highwater < skip_len);
		return highwater;
	}
	

	public String getContent(String endTag)
	{
		int bytes_read;
		String patStr = String.format("(?<=>).+");
		String str2 = String.format("</%s>", endTag);
		Pattern p = Pattern.compile(patStr, Pattern.DOTALL|Pattern.CASE_INSENSITIVE);

		try {
			stream.mark(READ_LEN);
			bytes_read = readBytes(READ_LEN);
			String str = new String(buf, 0, bytes_read, charset);
			Matcher m = p.matcher(str);
			int index = (str.toLowerCase().indexOf(str2) > 0)? str.toLowerCase().indexOf(str2) : 0;
			m.region(0, index);
			stream.reset();
			if ( m.find())
			{				
				return m.group();
			}
			return "";
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}
	}

	public String getString(int len)
	{
		try {
			stream.mark(len);
			stream.read(buf, 0, len);
			stream.reset();
			String ret = new String(buf, 0, len, charset);
			return ret;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return "";
	}

}